package com.yanxx.codegenerator.sdk;

import com.yanxx.codegenerator.CodeGenerator;
import com.yanxx.codegenerator.format.CodeFormatter;
import com.yanxx.codegenerator.format.impl.DatePrefixCodeFormatter;
import com.yanxx.codegenerator.format.impl.SimpleCodeFormatter;
import com.yanxx.codegenerator.reset.ResettableCodeGenerator;
import com.yanxx.codegenerator.impl.PersistentCodeGenerator;
import com.yanxx.codegenerator.impl.SequentialCodeGenerator;
import com.yanxx.codegenerator.reset.ResetStrategy;
import com.yanxx.codegenerator.reset.impl.DailyResetStrategy;
import com.yanxx.codegenerator.reset.impl.MonthlyResetStrategy;
import com.yanxx.codegenerator.reset.impl.WeeklyResetStrategy;
import com.yanxx.codegenerator.storage.CodeGeneratorStorage;
import com.yanxx.codegenerator.storage.impl.DatabaseStorage;
import com.yanxx.codegenerator.storage.impl.FileStorage;
import com.yanxx.codegenerator.storage.impl.RedisStorage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPool;

import javax.sql.DataSource;

import java.io.File;

/**
 * 编码生成器SDK
 * 提供简单的工厂方法和构建器模式来创建和配置编码生成器
 */
public class CodeGeneratorSDK {
    private static final Logger logger = LoggerFactory.getLogger(CodeGeneratorSDK.class);
    
    private CodeGeneratorSDK() {
        // 私有构造函数，防止实例化
    }
    
    /**
     * 创建一个简单的编码生成器（无持久化）
     *
     * @return 编码生成器实例
     */
    public static CodeGenerator createSimpleGenerator() {
        return new SequentialCodeGenerator();
    }
    
    /**
     * 创建一个简单的编码生成器（无持久化）
     *
     * @param prefix     编号前缀
     * @param codeLength 编号长度（不包括前缀）
     * @param startValue 起始编号值
     * @return 编码生成器实例
     */
    public static CodeGenerator createSimpleGenerator(String prefix, int codeLength, long startValue) {
        return new SequentialCodeGenerator(prefix, codeLength, startValue);
    }
    
    /**
     * 创建一个带文件持久化功能的编码生成器
     *
     * @param filePath 持久化文件路径
     * @return 编码生成器实例
     */
    public static CodeGenerator createPersistentGenerator(String filePath) {
        CodeGeneratorStorage storage = new FileStorage(filePath);
        CodeGenerator generator = new PersistentCodeGenerator(storage);
        generator.initialize();
        return generator;
    }
    
    /**
     * 创建一个带文件持久化功能的编码生成器
     *
     * @param filePath   持久化文件路径
     * @param prefix     编号前缀
     * @param codeLength 编号长度（不包括前缀）
     * @param startValue 起始编号值
     * @return 编码生成器实例
     */
    public static CodeGenerator createPersistentGenerator(String filePath, String prefix, int codeLength, long startValue) {
        CodeGeneratorStorage storage = new FileStorage(filePath);
        CodeGenerator generator = new PersistentCodeGenerator(prefix, codeLength, startValue, storage);
        generator.initialize();
        return generator;
    }
    
    /**
     * 创建一个带Redis持久化功能的编码生成器
     *
     * @param jedisPool Redis连接池
     * @param keyPrefix Redis键前缀
     * @return 编码生成器实例
     */
    public static CodeGenerator createRedisPersistentGenerator(JedisPool jedisPool, String keyPrefix) {
        CodeGeneratorStorage storage = new RedisStorage(jedisPool, keyPrefix);
        CodeGenerator generator = new PersistentCodeGenerator(storage);
        generator.initialize();
        return generator;
    }
    
    /**
     * 创建一个带Redis持久化功能的编码生成器
     *
     * @param jedisPool  Redis连接池
     * @param keyPrefix  Redis键前缀
     * @param prefix     编号前缀
     * @param codeLength 编号长度（不包括前缀）
     * @param startValue 起始编号值
     * @return 编码生成器实例
     */
    public static CodeGenerator createRedisPersistentGenerator(JedisPool jedisPool, String keyPrefix, 
                                                              String prefix, int codeLength, long startValue) {
        CodeGeneratorStorage storage = new RedisStorage(jedisPool, keyPrefix);
        CodeGenerator generator = new PersistentCodeGenerator(prefix, codeLength, startValue, storage);
        generator.initialize();
        return generator;
    }
    
    /**
     * 创建一个带数据库持久化功能的编码生成器
     *
     * @param dataSource  数据源
     * @param generatorId 生成器ID
     * @return 编码生成器实例
     */
    public static CodeGenerator createDatabasePersistentGenerator(DataSource dataSource, String generatorId) {
        CodeGeneratorStorage storage = new DatabaseStorage(dataSource, generatorId);
        CodeGenerator generator = new PersistentCodeGenerator(storage);
        generator.initialize();
        return generator;
    }
    
    /**
     * 创建一个带数据库持久化功能的编码生成器
     *
     * @param dataSource  数据源
     * @param generatorId 生成器ID
     * @param prefix      编号前缀
     * @param codeLength  编号长度（不包括前缀）
     * @param startValue  起始编号值
     * @return 编码生成器实例
     */
    public static CodeGenerator createDatabasePersistentGenerator(DataSource dataSource, String generatorId,
                                                                String prefix, int codeLength, long startValue) {
        CodeGeneratorStorage storage = new DatabaseStorage(dataSource, generatorId);
        CodeGenerator generator = new PersistentCodeGenerator(prefix, codeLength, startValue, storage);
        generator.initialize();
        return generator;
    }
    
    /**
     * 创建按天重置的编码生成器
     *
     * @param prefix     编号前缀
     * @param codeLength 编号长度（不包括前缀）
     * @param startValue 起始编号值
     * @return 编码生成器实例
     */
    public static CodeGenerator createDailyResetGenerator(String prefix, int codeLength, long startValue) {
        return new ResettableCodeGenerator(startValue, prefix, codeLength, new DailyResetStrategy());
    }
    
    /**
     * 创建按周重置的编码生成器
     *
     * @param prefix     编号前缀
     * @param codeLength 编号长度（不包括前缀）
     * @param startValue 起始编号值
     * @return 编码生成器实例
     */
    public static CodeGenerator createWeeklyResetGenerator(String prefix, int codeLength, long startValue) {
        return new ResettableCodeGenerator(startValue, prefix, codeLength, new WeeklyResetStrategy());
    }
    
    /**
     * 创建按月重置的编码生成器
     *
     * @param prefix     编号前缀
     * @param codeLength 编号长度（不包括前缀）
     * @param startValue 起始编号值
     * @return 编码生成器实例
     */
    public static CodeGenerator createMonthlyResetGenerator(String prefix, int codeLength, long startValue) {
        return new ResettableCodeGenerator(startValue, prefix, codeLength, new MonthlyResetStrategy());
    }
    
    /**
     * 创建带日期前缀的编码生成器
     *
     * @param prefix      固定前缀
     * @param dateFormat  日期格式
     * @param codeLength  编号长度（不包括前缀和日期）
     * @param startValue  起始编号值
     * @return 编码生成器实例
     */
    public static CodeGenerator createDatePrefixGenerator(String prefix, String dateFormat, int codeLength, long startValue) {
        CodeFormatter formatter = new DatePrefixCodeFormatter(prefix, dateFormat, codeLength);
        return new SequentialCodeGenerator(startValue, formatter);
    }
    
    /**
     * 获取编码生成器构建器
     *
     * @return 构建器实例
     */
    public static Builder builder() {
        return new Builder();
    }
    
    /**
     * 编码生成器构建器
     * 用于灵活配置和创建编码生成器
     */
    public static class Builder {
        private String prefix = "";
        private int codeLength = 6;
        private long startValue = 0;
        private String filePath = null;
        private CodeFormatter formatter = null;
        private ResetStrategy resetStrategy = null;
        private String dateFormat = null;
        
        /**
         * 设置编号前缀
         *
         * @param prefix 编号前缀
         * @return 构建器实例
         */
        public Builder prefix(String prefix) {
            this.prefix = prefix;
            return this;
        }
        
        /**
         * 设置编号长度（不包括前缀）
         *
         * @param codeLength 编号长度
         * @return 构建器实例
         */
        public Builder codeLength(int codeLength) {
            this.codeLength = codeLength;
            return this;
        }
        
        /**
         * 设置起始编号值
         *
         * @param startValue 起始编号值
         * @return 构建器实例
         */
        public Builder startValue(long startValue) {
            this.startValue = startValue;
            return this;
        }
        
        /**
         * 设置持久化文件路径
         *
         * @param filePath 文件路径
         * @return 构建器实例
         */
        public Builder persistentFile(String filePath) {
            this.filePath = filePath;
            return this;
        }
        
        /**
         * 设置自定义格式化器
         *
         * @param formatter 格式化器
         * @return 构建器实例
         */
        public Builder formatter(CodeFormatter formatter) {
            this.formatter = formatter;
            return this;
        }
        
        /**
         * 设置日期格式
         * 会创建一个DatePrefixCodeFormatter
         *
         * @param dateFormat 日期格式，如"yyyyMMdd"
         * @return 构建器实例
         */
        public Builder dateFormat(String dateFormat) {
            this.dateFormat = dateFormat;
            return this;
        }
        
        /**
         * 设置按天重置策略
         *
         * @return 构建器实例
         */
        public Builder resetDaily() {
            this.resetStrategy = new DailyResetStrategy();
            return this;
        }
        
        /**
         * 设置按周重置策略
         *
         * @return 构建器实例
         */
        public Builder resetWeekly() {
            this.resetStrategy = new WeeklyResetStrategy();
            return this;
        }
        
        /**
         * 设置按月重置策略
         *
         * @return 构建器实例
         */
        public Builder resetMonthly() {
            this.resetStrategy = new MonthlyResetStrategy();
            return this;
        }
        
        /**
         * 设置自定义重置策略
         *
         * @param resetStrategy 重置策略
         * @return 构建器实例
         */
        public Builder resetStrategy(ResetStrategy resetStrategy) {
            this.resetStrategy = resetStrategy;
            return this;
        }
        
        /**
         * 构建编码生成器实例
         *
         * @return 编码生成器实例
         */
        public CodeGenerator build() {
            // 确定使用的格式化器
            CodeFormatter actualFormatter = formatter;
            if (actualFormatter == null) {
                if (dateFormat != null) {
                    actualFormatter = new DatePrefixCodeFormatter(prefix, dateFormat, codeLength);
                } else {
                    actualFormatter = new SimpleCodeFormatter(prefix, codeLength);
                }
            }
            
            if (filePath != null && !filePath.isEmpty()) {
                // 创建持久化目录
                File file = new File(filePath);
                File parentDir = file.getParentFile();
                if (parentDir != null && !parentDir.exists()) {
                    boolean created = parentDir.mkdirs();
                    if (!created) {
                        logger.warn("Failed to create directory for persistent file: {}", parentDir);
                    }
                }
                
                // 创建带持久化功能的生成器
                CodeGeneratorStorage storage = new FileStorage(filePath);
                CodeGenerator generator;
                
                if (resetStrategy != null) {
                    // 创建可重置的持久化生成器
                    generator = new ResettableCodeGenerator(startValue, actualFormatter, resetStrategy, storage);
                } else {
                    // 创建普通持久化生成器
                    generator = new PersistentCodeGenerator(storage);
                }
                
                generator.initialize();
                return generator;
            } else if (resetStrategy != null) {
                // 创建可重置的生成器（无持久化）
                return new ResettableCodeGenerator(startValue, actualFormatter, resetStrategy);
            } else {
                // 创建简单生成器
                return new SequentialCodeGenerator(startValue, actualFormatter);
            }
        }
    }
}